﻿namespace OutLook.Module.Load
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using OutLook.Module.Load.Contracts;
    using OutLook.Module.Infrastructure;
    using OutLook.Module.Infrastructure.Interfaces;
    using OutLook.Model.Domains;
    using System.IO;
    using System.Text.RegularExpressions;
    using OutLook.Model.Infrastructure;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class UserController : DomainControllerBase, IUserContract
    {
        #region Constructors

        public UserController(IRepository context)
            : base(context)
        {
            ///TODO:Set normal repository (cause this is a mock)
            //m_Resolver = new LocalPathResolver();
            //Storage.Initialize<User>(Path.Combine(m_Resolver.ResolvePath(@"Data\Users"), "Users.xml"));
        }

        #endregion

        #region IUserController Implementation

        public void Registrate(User user)
        {
            if (!user.Validate())
                throw new ArgumentException();

            List<User> list = new List<User>(Storage.Enumerate<User>());

            if (list.IndexOf(user) != -1)
                throw new ArgumentException("You are registrated!");

            if (list.FindAll(u => u.Login.Equals(user.Login)).Count != 0)
                throw new ArgumentException("This login already exists!");


            Storage.Add<User>(user);
        }

        public bool LogIn(string login, string password)
        {
            List<User> list = new List<User>(Storage.Enumerate<User>());
            User existUser = list.Find(el => el.Login == login && el.Password == password);
            if (existUser == null)
                return false;

            m_CurrentUser = existUser;
            return true;
        }

        public void LogOut()
        {
            if (m_CurrentUser == null)
                throw new InvalidOperationException();

            m_CurrentUser = default(User);
        }

        public bool ChangePassword(string currentPassword, string newPassword, string newPasswordConfirm)
        {
            if (m_CurrentUser == null)
                throw new InvalidOperationException();

            if (!m_CurrentUser.Password.Equals(currentPassword))
                throw new ArgumentException("Password doesn't match!");

            if (!newPassword.Equals(newPasswordConfirm))
                throw new ArgumentException("Passwords don't equals");

            if (newPassword.Length > Constants.MAX_PASSWORD_LENGTH)
                throw new ArgumentException("Long password");

            if (newPassword.Length < Constants.MAX_PASSWORD_LENGTH)
                throw new ArgumentException("Short password");

            m_CurrentUser.Password = newPassword;
            Storage.Update<User>(m_CurrentUser);

            return true;
        }

        public bool RecoverPassword(string email)
        {
            if (!Regex.IsMatch(email, Constants.EMAIL_REGULAR_EXPRESSION))
                return false;

            List<User> list = new List<User>(Storage.Enumerate<User>());
            User fromList = list.Find(el => el.Email == email);

            if (fromList == null)
                return false;

            ///TODO:Send message with new password

            return true;
        }

        public User ViewProfile()
        {
            if (m_CurrentUser == null)
                throw new InvalidOperationException();

            return m_CurrentUser;
        }

        public bool EditProfile(User user)
        {
            if (m_CurrentUser == null)
                return false;

            Storage.Update<User>(user);

            return true;
        }

        public User GetCurrentUser()
        {
            return m_CurrentUser;
        }

        #endregion

        #region DomainControllerBase members

        protected override void Dispose(bool dispoceManged)
        {
            if (m_Disposed)
                return;

            m_CurrentUser = null;

            m_Disposed = true;
        }

        #endregion        

        #region Fields

        private bool m_Disposed = false;
        private static User m_CurrentUser = default(User);
        private IPathResolver m_Resolver;
        private string m_CurrentCaseName = default(string);

        #endregion
    }
}
